// Command鏂囦欢淇℃伅澶勭悊绫�
package com.config;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.databus.*;
import com.packet.PackageHeader;
import com.packet.PackageHeader.MsgType;
import com.protobuf.MsgExpress;

public class CommandParse {
	
	private static HashMap<Integer, String> mapCommand2Class;
	private static HashMap<String, Integer> mapClass2Command;
	private static HashMap<String, Integer> mapClass2Service;
	private static HashMap<Integer, MsgExpress.RegisterService> mapServiceInfo;
	private static HashMap<Integer,MsgExpress.FunctionInfo> mapFunctionInfo;
	private static Boolean bwrite=false;
	
	static 
	{
		mapCommand2Class=new HashMap<Integer, String>();
		mapClass2Command=new HashMap<String, Integer>();
		mapClass2Service=new HashMap<String, Integer>();
		mapServiceInfo=new HashMap<Integer, MsgExpress.RegisterService>();
		mapFunctionInfo=new  HashMap<Integer,MsgExpress.FunctionInfo>();
		bwrite = true;

		Register(0, "MsgExpress","com.protobuf","MsgExpress.ErrMessage");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.CommonResponse");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.PublishData");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.Login");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.ServiceInfo");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.LoginInfo");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.LoginResponse");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.Logout");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.HeartBeat");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.HeartBeatResponse");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.SimpleSubscription");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.SubscribeData");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.UnSubscribeData");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.ComplexSubscribeData");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.GetAppList");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.AppList");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.GetAppInfo");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.AppInfo");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.UpdateAppStatus");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.AppServerList");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.BrokerInfo");
		Register(0, "MsgExpress","com.protobuf","MsgExpress.RegisterService");

		Register(1, "Gateway","com.protobuf","Gateway.CommonResponse");
		Register(1, "Gateway","com.protobuf","Gateway.Login");
		Register(1, "Gateway","com.protobuf","Gateway.Logout");
		Register(1, "Gateway","com.protobuf","Gateway.Subscribe");
		Register(1, "Gateway","com.protobuf","Gateway.SubscribeResult");
		
		bwrite=false;
	}

	public static int Hashcode(String str)
	{
		int h = 0;
		byte[] b=str.getBytes();
		for (int i = 0; i < b.length; i++)
		{
			h = 31 * h + b[i];
		}
		return h;
	}
	
	public synchronized static int GetCommand(String classname)
	{
		if (mapClass2Command.containsKey(classname))
			return mapClass2Command.get(classname);
		else
		{
			Log.warn("cant find command for class name,class="+ classname);
			return Hashcode(classname);
		}
	}
	public synchronized static String GetClass(int command)
	{
		if (mapCommand2Class.containsKey(command))
			return mapCommand2Class.get(command);
		else
			Log.error("cant find class name for command,command="+ command);
		return "";
	}
	
	public synchronized static int GetServiceId(String classname)
	{
		if (mapClass2Service.containsKey(classname))
			return mapClass2Service.get(classname);
		else
			Log.error("cant find serviceid,class="+ classname);
		return 0;
	}
	
	public synchronized static int GetServiceId(int command)
	{
		if (!mapCommand2Class.containsKey(command))
		{
			Log.error("cant find class name for command,command="+ command);
		}
		else
		{
			return GetServiceId(mapCommand2Class.get(command));
		}
		return 0;
	}

	public synchronized static void Register(int serviceid,String servicename, String javapackage,String funname)
	{
		int command =  Hashcode(funname);
		String classname=funname;
		if(javapackage.length()>0)
		{
			classname=javapackage+"."+funname.replace('.','$');
		}
		if ( mapCommand2Class.containsKey(command) )
		{
			if(!mapCommand2Class.get(command).equals(classname))
				Log.error("Hashcode confict,class:"+classname);
		}
		else if (mapClass2Service.containsKey(classname) )
		{
			if(mapClass2Service.get(classname)!=serviceid)
				Log.error("Class and services dismatch,classname:"+ classname);
		}
		else
		{
			mapCommand2Class.put(command, classname);
			mapClass2Command.put(classname,command);
			mapClass2Service.put(classname, serviceid);
			Log.info("register api,service="+serviceid+",command="+command+",classname="+classname);
		}
	}
	
	public synchronized static void Register(com.protobuf.MsgExpress.RegisterService registerservice)
	{
		int serviceid = registerservice.getServiceid();
		String servicename=registerservice.getServicename();
		String packname=registerservice.getJavapackage();
		for (int i = 0; i < registerservice.getFunctionsCount(); i++)
		{
			Register(serviceid,servicename,packname,registerservice.getFunctions(i));
		}
		mapServiceInfo.put(serviceid, registerservice);
		//Log.g_logger.info("Register service:" + registerservice.toString());
	}

	public synchronized static void Register(com.protobuf.MsgExpress.ServiceInfo serviceInfo)
	{
		int serviceid = serviceInfo.getServiceid();
		String servicename=serviceInfo.getServicename();
		for (int i = 0; i < serviceInfo.getFunctionsCount(); i++)
		{
			com.protobuf.MsgExpress.FunctionInfo fun=serviceInfo.getFunctions(i);
			if(fun.getParamsCount()==1 ) {
				String fullname=fun.getParams(0).getFulltypename();
				String simplename=fun.getParams(0).getSimpletypename();
				String java_package=fullname.replace("."+simplename,"");
				Register(serviceid, servicename, java_package, fun.getFunctionname());
				mapFunctionInfo.put(Hashcode(fun.getFunctionname()),fun);
			}
		}
		//mapServiceInfo.put(serviceid, registerservice);
		Log.info("Register service:" + serviceInfo.toString());
	}

	public synchronized static MsgExpress.FunctionInfo GetFunctionInfo(int funid)
	{
		return mapFunctionInfo.get(funid);
	}
}
